Packaging Java Applications as JAR and WAR Files
Course: Advanced Java Training
Topic: Packaging Java Applications as JAR and WAR Files
Course Link: Advanced Java Training Course
Demo Link: Register for a Course Demo
Website: JustAcademy
1. Introduction to Java Application Packaging
Java application packaging is the process of collecting compiled Java classes, configuration files, resources, and other required components into a distributable archive. Packaging makes it easier to run, share, deploy, and maintain Java applications across different environments.
During development, a Java application may contain many source files, libraries, configuration files, and resources. Instead of transferring each file individually, developers create a single package that contains the files needed for deployment.
The two common packaging formats are:
- JAR (Java Archive): Commonly used for Java libraries, command-line applications, utilities, and executable Spring Boot applications.
- WAR (Web Application Archive): Used to package Java web applications for deployment to servlet containers or compatible application servers.
The choice between JAR and WAR depends on the application's architecture, runtime requirements, and deployment environment.
2. Learning Objectives
- Understand Java application packaging and deployment.
- Learn the structure and purpose of JAR and WAR files.
- Understand the differences between JAR and WAR packaging.
- Create JAR files using the JDK and Maven.
- Configure Maven projects to generate JAR and WAR artifacts.
- Package Spring Boot applications as executable JAR files.
- Configure Spring Boot applications for WAR deployment.
- Understand manifest files, dependencies, resources, and build outputs.
- Run packaged applications and troubleshoot common deployment problems.
3. What Is a JAR File?
A JAR file is a ZIP-based archive format used to bundle Java classes, metadata, resources, and optionally other files into a single archive. JAR files are commonly used to distribute reusable Java libraries and applications.
A JAR file may contain compiled .class files, properties files, XML configuration, images, text resources, and metadata stored under META-INF.
3.1 Common Uses of JAR Files
- Packaging standalone Java applications.
- Distributing reusable Java libraries.
- Sharing utility classes between projects.
- Packaging Spring Boot applications with their runtime dependencies.
- Distributing command-line tools and background services.
3.2 Example JAR Structure
employee-app.jar
├── META-INF/
│ └── MANIFEST.MF
├── com/
│ └── example/
│ ├── Employee.class
│ └── Main.class
└── application.properties
This is an illustrative structure for a conventional JAR. The exact contents depend on the build system and packaging configuration. An executable Spring Boot JAR uses a different layout, commonly including BOOT-INF/classes and BOOT-INF/lib.
4. What Is a WAR File?
A WAR file is a Web Application Archive designed to package Java web applications. It can include servlet-based application classes, web resources, configuration files, and application libraries.
WAR files are commonly deployed to servlet containers such as Apache Tomcat or other compatible application servers. The container provides the web runtime required to host the application.
4.1 Common Uses of WAR Files
- Deploying traditional Java web applications.
- Hosting servlet-based applications on an external container.
- Packaging applications that follow a centralized application-server deployment model.
- Deploying Spring Boot applications to an external servlet container when configured for WAR packaging.
4.2 Example WAR Structure
employee-app.war
├── META-INF/
│ └── MANIFEST.MF
├── WEB-INF/
│ ├── classes/
│ │ └── com/example/EmployeeController.class
│ ├── lib/
│ │ └── application-library.jar
│ └── web.xml
├── index.html
└── css/
└── style.css
This is a representative traditional WAR layout. Depending on the framework and servlet specification, a web.xml file may not be required. An executable Spring Boot WAR can also contain WEB-INF/lib-provided for dependencies used when running the archive directly.
5. Difference Between JAR and WAR Files
| Feature |
JAR |
WAR |
| Full form |
Java Archive |
Web Application Archive |
| Primary purpose |
Libraries and Java applications |
Java web applications |
| Common runtime |
Java runtime; executable Spring Boot applications may include an embedded server |
Usually a servlet container or compatible application server |
| Typical structure |
Class files, resources, metadata, and possibly dependencies |
Web resources, WEB-INF/classes, libraries, and metadata |
| Execution |
An executable JAR can be started with java -jar |
A traditional WAR is deployed to a compatible container; an executable Spring Boot WAR can also be started with java -jar |
| Common build output |
application.jar |
application.war |
| Typical deployment |
Standalone application or service |
Web application hosted by a server |
6. Understanding Java Application Build Tools
Build tools automate compilation, dependency management, testing, packaging, and distribution. Maven and Gradle are widely used in Java projects.
6.1 Apache Maven
Maven uses a project configuration file named pom.xml. The POM defines project metadata, dependencies, plugins, and build configuration.
Important Maven packaging commands include:
mvn clean
mvn compile
mvn test
mvn package
mvn verify
mvn install
6.2 Gradle
Gradle is another build automation tool that uses files such as build.gradle or build.gradle.kts. Spring Boot projects commonly use Gradle tasks such as bootJar and bootWar to create executable archives.
7. Creating a Basic JAR File Using the JDK
The JDK includes the jar tool, which can package compiled classes and resources into an archive.
Step 1: Create a Java Class
public class Main {
public static void main(String[] args) {
System.out.println("Java application is running.");
}
}
Step 2: Compile the Java Class
javac Main.java
This generates Main.class in the current directory.
Step 3: Create a JAR Archive
jar --create --file app.jar Main.class
The command packages the compiled class into app.jar. This archive contains the class, but it does not yet specify which class should be launched automatically.
Step 4: Create an Executable JAR
For an executable JAR, specify the entry-point class using the manifest option:
jar --create --file app.jar --main-class Main Main.class
Step 5: Run the JAR
java -jar app.jar
Expected output:
Java application is running.
The JAR must contain a valid entry point and any dependencies needed by the application must be available at runtime. This simple example has no external dependencies.
8. Understanding the JAR Manifest File
The manifest file is metadata stored in META-INF/MANIFEST.MF. It can define information about the archive, including its main class.
Example Manifest
Manifest-Version: 1.0
Main-Class: Main
The Main-Class attribute identifies the class containing the application's entry point. That class must define a suitable method, typically public static void main(String[] args).
For a conventional JAR with external dependencies, the manifest may also specify a class path. However, a manifest class path must refer to dependency locations that are actually available at runtime. Spring Boot's executable archive format handles dependencies differently through its loader.
9. Creating a JAR File Using Maven
Maven simplifies packaging by automatically compiling source files, copying resources, running configured tests, and creating the archive during the build lifecycle.
9.1 Standard Maven Project Structure
my-java-app/
├── pom.xml
└── src/
├── main/
│ ├── java/
│ │ └── com/example/Main.java
│ └── resources/
│ └── application.properties
└── test/
└── java/
9.2 Basic Maven Configuration
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-java-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
This configuration demonstrates a standard Maven JAR project targeting Java 17. The selected Java release must be supported by the installed JDK and the application's dependencies.
9.3 Build the JAR
mvn clean package
Maven creates the JAR file in the target directory, typically named:
target/my-java-app-1.0.0.jar
The exact filename depends on the project's artifact ID, version, and any custom build settings.
10. Creating a Spring Boot Executable JAR
Spring Boot supports executable JAR packaging that includes the application and its runtime dependencies. When configured with the Spring Boot Maven or Gradle plugin, the archive can generally be started using java -jar.
10.1 Example Spring Boot Main Class
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
10.2 Maven Packaging Configuration
In a Spring Boot Maven project, the relevant plugin is commonly configured as follows. When the project uses the Spring Boot parent, the executable archive repackaging execution is typically preconfigured.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
10.3 Build the Executable JAR
mvn clean package
After a successful build, locate the generated archive in the target directory.
10.4 Run the Application
java -jar target/my-java-app-1.0.0.jar
If the project is a web application, its embedded server can start as part of the application, provided the appropriate web dependencies and configuration are present.
11. Understanding the Spring Boot Executable JAR Structure
A repackaged Spring Boot JAR has a layout designed to load application classes and nested dependency JARs.
my-application.jar
├── META-INF/
│ └── MANIFEST.MF
├── org/springframework/boot/loader/
├── BOOT-INF/
│ ├── classes/
│ │ └── com/example/DemoApplication.class
│ └── lib/
│ ├── spring-core.jar
│ └── other-dependency.jar
This is an illustrative layout. The exact loader paths and archive structure depend on the Spring Boot version. The important point is that application classes and dependencies are organized inside the executable archive so the Spring Boot launcher can load them.
12. What Is a WAR Packaging Configuration?
WAR packaging is useful when a Java web application must be deployed to an external servlet container. In Maven, the project's packaging is configured using the <packaging> element.
12.1 Change the Packaging Type
<packaging>war</packaging>
For a standard Maven web project, the WAR plugin is responsible for producing the web archive. Spring Boot projects commonly use the Spring Boot Maven plugin to create an executable WAR when required.
12.2 Configure the Maven WAR Plugin
A conventional web application may use a WAR plugin configuration such as:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.4.0</version>
</plugin>
</plugins>
</build>
Use a plugin version compatible with your project's Maven and Java requirements. If the Spring Boot parent already manages the plugin, avoid unnecessary version overrides.
13. Packaging a Spring Boot Application as a WAR
A Spring Boot application can be configured as a WAR for deployment to an external servlet container. This usually requires changing the packaging type, adjusting the servlet container dependency scope, and making the application compatible with traditional servlet-container initialization.
13.1 Configure the POM
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
This is a representative configuration for a Spring Boot version that uses these dependency coordinates. Keep dependency versions aligned with the Spring Boot version and dependency management used by the project.
The provided scope indicates that the external container supplies the servlet runtime for traditional deployment. For an executable Spring Boot WAR, the packaging plugin places provided runtime dependencies in a separate location so they do not conflict with the external container's libraries.
13.2 Configure the Application Class
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder application) {
return application.sources(DemoApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Extending SpringBootServletInitializer allows a suitable Spring Boot application to be initialized by a traditional servlet container. The main() method remains available for running the application directly when the WAR has been packaged for executable use.
13.3 Build the WAR
mvn clean package
The output is typically created in the target directory, for example:
target/my-java-app-1.0.0.war
14. Deploying a WAR to an External Servlet Container
After building a WAR, deploy it to a servlet container compatible with the application's Spring Boot and Jakarta Servlet versions.
General Deployment Steps
- Build the application with Maven.
- Confirm that the WAR file was generated successfully.
- Check that the target container supports the servlet specification required by the application.
- Deploy the WAR using the container's supported deployment process.
- Start or reload the application according to the container's instructions.
- Review application and container logs for startup errors.
- Test the application's endpoints using a browser, HTTP client, or automated tests.
For example, a Tomcat installation may support deploying a WAR through its configured deployment directory or management interface. The exact procedure depends on the Tomcat version, security configuration, and deployment policy.
15. Running an Executable Spring Boot WAR
A Spring Boot WAR configured for executable use can also be launched directly, provided its packaging and dependencies support that mode.
java -jar target/my-java-app-1.0.0.war
This does not mean every WAR file can be started using java -jar. A traditional WAR intended only for external deployment may not include the necessary Spring Boot launcher and runtime packaging.
16. Understanding the Maven Build Lifecycle
Maven follows a sequence of lifecycle phases to validate, compile, test, package, and distribute an application. Running a later phase also executes the earlier phases in that lifecycle.
| Phase |
Purpose |
| validate |
Checks that the project is correctly configured. |
| compile |
Compiles the main source code. |
| test |
Runs configured unit tests. |
| package |
Creates the distributable archive, such as a JAR or WAR. |
| verify |
Runs additional checks configured in the build lifecycle. |
| install |
Installs the built artifact into the local Maven repository. |
| deploy |
Publishes the artifact to a configured remote repository. |
For example, mvn package normally compiles the code, runs tests, and creates the configured archive. The exact operations depend on the project's plugins and lifecycle configuration.
17. Important Maven Commands
| Command |
Description |
mvn clean |
Removes the build output directory. |
mvn compile |
Compiles application source code. |
mvn test |
Runs configured tests. |
mvn package |
Builds the configured JAR or WAR artifact. |
mvn clean package |
Cleans old output and creates a fresh package. |
mvn verify |
Runs the verification lifecycle, including configured checks. |
mvn install |
Installs the artifact in the local Maven repository. |
mvn -DskipTests package |
Skips test execution while packaging; test compilation may still occur. |
Skipping tests should generally be limited to situations where it is appropriate. For normal development and release builds, run the tests to reduce the risk of shipping broken code.
18. Including Dependencies in a Packaged Application
A Java application may depend on third-party libraries. The packaging strategy determines how these libraries are made available at runtime.
18.1 Conventional JAR
A conventional JAR generally contains the project's compiled classes and resources, but it does not automatically include every dependency. External libraries must be supplied through the runtime classpath or another packaging mechanism.
18.2 Spring Boot Executable JAR
A Spring Boot executable JAR typically includes application dependencies inside the archive under BOOT-INF/lib, allowing the application to run without manually listing each dependency on the classpath.
18.3 WAR File
A traditional WAR normally includes web application dependencies in WEB-INF/lib. Some runtime libraries may be supplied by the servlet container and therefore should not be packaged as ordinary application libraries.
19. Managing Application Configuration
Java applications commonly require configuration such as database connection details, server ports, logging settings, and API endpoints. Some configuration files may be packaged into the archive, while environment-specific values should be supplied externally when practical.
Example application.properties
spring.application.name=employee-app
server.port=8080
Place classpath configuration files in the standard resources directory, such as src/main/resources. For production deployments, avoid embedding passwords, private keys, or other secrets directly in source code or packaged configuration files.
20. Naming and Versioning Artifacts
Artifact names should make the application and version easy to identify. Maven typically generates filenames from the artifact ID, version, and packaging type.
Examples:
employee-app-1.0.0.jar
employee-app-1.0.0.war
Versioning helps teams distinguish releases, roll back to earlier builds, and track which artifact has been deployed. A custom Maven finalName can be used when a stable filename is required, but the release version should still be tracked through build metadata or the deployment process.
21. Inspecting and Verifying JAR and WAR Files
After packaging, inspect the generated artifact to confirm that the required classes, resources, and metadata are present.
List JAR Contents
jar --list --file target/employee-app-1.0.0.jar
Extract a Conventional Archive
mkdir extracted
cd extracted
jar --extract --file ../target/employee-app-1.0.0.jar
For a Spring Boot executable archive, the contents may include nested dependency archives and a specialized launcher layout. Some archive utilities do not treat nested JARs as ordinary classpath entries.
Check Java Version
java -version
javac -version
Make sure the runtime Java version is compatible with the Java release used to compile the application and with its framework and dependency requirements.
22. Common Packaging Errors and Solutions
| Error or Problem |
Possible Cause |
Suggested Solution |
| Unable to access JAR file |
Incorrect path or missing artifact |
Check the filename and target directory. |
| No main manifest attribute |
Executable entry point is not configured |
Configure the main class or Spring Boot packaging plugin. |
| ClassNotFoundException |
Required class or library is missing from the runtime classpath |
Inspect dependency configuration and archive contents. |
| Unsupported class file version |
Runtime Java is older than the version used to compile the class |
Use a compatible JDK or compile for the required release. |
| WAR fails during deployment |
Incompatible container or incorrect runtime dependency scope |
Check servlet compatibility, dependency scope, and logs. |
| Port already in use |
Another process is using the configured port |
Stop the conflicting process or configure another port. |
| Application configuration not found |
Resource was not included or external configuration is incorrect |
Inspect resources and verify configuration paths. |
| Tests fail during packaging |
Compilation errors or failing tests |
Review Maven output and resolve test failures. |
23. Best Practices for Packaging Java Applications
- Choose JAR or WAR based on the actual deployment requirements.
- Use Maven or Gradle to create repeatable, automated builds.
- Keep dependency versions consistent and compatible.
- Run automated tests before producing release artifacts.
- Verify that the archive contains the required classes and resources.
- Keep secrets outside the packaged artifact wherever possible.
- Use clear artifact names and version numbers.
- Check Java and servlet-container compatibility before deployment.
- Use executable Spring Boot JARs for simple standalone deployment when suitable.
- Use WAR packaging when deployment to an external servlet container is required.
- Test the packaged artifact in a staging environment before production release.
- Keep build logs and artifact checksums when reproducibility and traceability are important.
24. Practical Project: Package an Employee Management Application
Build a small employee management application using Java and Spring Boot, and package it in both JAR and WAR formats in separate build configurations.
Project Requirements
- Create a Spring Boot application with a main application class.
- Add an employee REST controller and service.
- Configure application properties.
- Build and run the application as an executable JAR.
- Change the build configuration to produce a WAR.
- Configure the application for external servlet-container deployment.
- Verify the artifact contents and test the application's endpoints.
- Document the build and deployment steps.
Example Build Workflow
# Clean and build the JAR configuration
mvn clean package
# Run the executable Spring Boot JAR
java -jar target/employee-app-1.0.0.jar
# After changing the project to WAR packaging
mvn clean package
# Deploy the WAR to a compatible external container
# or run it directly if it is configured as an executable Spring Boot WAR
Use separate configuration branches or project profiles if the project needs to maintain both packaging types. Avoid assuming that one build configuration automatically produces both a conventional JAR and a WAR.
25. Exercises for Practice
- Create a simple Java class and package it into a JAR using the JDK.
- Add a manifest entry and run the JAR using
java -jar.
- Create a Maven project and generate a JAR using
mvn package.
- Configure the Spring Boot Maven plugin and run the executable JAR.
- Change a web application to WAR packaging.
- Configure a Spring Boot application to support external servlet-container initialization.
- Inspect the generated archive and verify that important resources are present.
- Intentionally configure an incorrect main class and investigate the resulting error.
- Check compatibility between the compiled Java version and the runtime version.
- Write a deployment checklist for a staging environment.
26. Interview Questions and Answers
Q1. What is a JAR file?
A JAR file is a Java Archive used to bundle Java classes, resources, metadata, and optionally other files into one archive.
Q2. What is a WAR file?
A WAR file is a Web Application Archive used to package Java web applications for deployment to compatible servlet containers or application servers.
Q3. What is the main difference between JAR and WAR?
JAR is a general archive format for Java libraries and applications, while WAR is designed for web applications. Executable Spring Boot JARs commonly run with an embedded server, whereas traditional WARs are deployed to an external container.
Q4. How do you create a JAR using Maven?
Run mvn package or mvn clean package in the Maven project directory.
Q5. How do you run an executable JAR?
Use the command java -jar application.jar, assuming the archive is executable and its runtime requirements are satisfied.
Q6. What is the purpose of MANIFEST.MF?
The manifest stores archive metadata. For an executable conventional JAR, its Main-Class attribute identifies the application's entry-point class.
Q7. What does the Spring Boot Maven plugin do?
It supports Spring Boot-specific build operations, including repackaging JAR or WAR artifacts so they can be executable when configured appropriately.
Q8. Where does Maven store generated artifacts?
Maven normally stores build outputs in the project's target directory.
Q9. How do you configure Maven to create a WAR?
Set the project's packaging to war and ensure the required WAR plugin and application configuration are present.
Q10. Why is a servlet container dependency often marked provided for WAR deployment?
The external servlet container supplies the required runtime libraries, so the application should avoid conflicting with the container's own servlet runtime.
Q11. Can a WAR file be executed using java -jar?
Some Spring Boot WARs are configured to run this way. A traditional WAR intended only for external deployment is not necessarily executable.
Q12. What is the Maven package phase?
The package phase creates the project's distributable artifact after the earlier required lifecycle phases have run.
Q13. What causes a No main manifest attribute error?
The JAR may lack an appropriate entry point in its manifest or may not have been packaged as an executable application.
Q14. What is the purpose of mvn clean package?
It removes previous build output and then executes the build lifecycle through the package phase to create a fresh artifact.
Q15. How should developers choose between JAR and WAR?
Choose based on the runtime and deployment model: standalone execution often suits executable JARs, while external servlet-container deployment may require a WAR.
27. Quick Revision Checklist
- Understand the purpose of JAR and WAR formats.
- Know the differences between conventional archives and executable Spring Boot archives.
- Understand Maven's build lifecycle and packaging configuration.
- Know how to create and run an executable JAR.
- Understand the WAR structure and external deployment process.
- Know the role of the manifest and main class.
- Check dependency scopes and Java runtime compatibility.
- Inspect build output and resolve packaging errors.
- Run tests and verify the final artifact before deployment.
28. Conclusion
Packaging Java applications as JAR and WAR files is an important part of Java development and deployment. JAR files are commonly used for libraries and standalone applications, while WAR files are intended for web applications that run in compatible servlet containers. Spring Boot supports executable JARs and can also create executable WARs when configured appropriately.
Understanding build tools, dependency management, manifest metadata, packaging configuration, and deployment requirements helps developers create reliable and portable application artifacts. Practicing both formats provides a strong foundation for deploying Java and Spring Boot applications across development, testing, staging, and production environments.
Learn More with JustAcademy
Explore the Advanced Java Training Course to continue learning about Java development, Spring Boot, application packaging, and deployment.
Register for a Course Demo to learn more about the training.
Visit the JustAcademy Website for additional courses and learning resources.